﻿import com.dmotiko.util.Point;
import com.dmotiko.lib.EventDispatcherPro;
import mx.transitions.Tween;
import mx.utils.Delegate;
import com.dmotiko.general.*

class com.dmotiko.general.BaseClip extends MovieClip {
	
   public var addEventListener:Function;
   public var removeEventListener:Function;
   public var dispatchEvent:Function; 
   
   private var data:Object;
   private var size:Point;
   private var tweens:Array;
   private var bShowed:Boolean;
   	
	private function BaseClip(){
		EventDispatcherPro.initialize(this);
		initClip();
		if(this._parent.childLoaded){
			addEventListener(BaseClipEvent.LOADED, Delegate.create(this._parent, this._parent.childLoaded));
			dispatchEvent( { type: BaseClipEvent.LOADED, target: this});
		}
	}
	
	/**
	 * @author: sminutoli
	 * @usage:  para casos en los que los listeners todavia no existen cuando se inicializa el clip
	 */
	public function initListeners() { return; }
	
	/**
	 * @author: sminutoli
	 * @usage:  deja que se inicialicen primero las variables y luego tira el evento de onLoad. Su uso es para la herencia
	 */
	private function initClip(){
		bShowed = true;
		return;
	}
	
	public function getData():Object {
		return this.data;
	}
	
	public function setData(data:Object):Void {
		this.data = data;
		this.dispatchEvent( { type: BaseClipEvent.DATA_CHANGED, target: this } );
		refreshData();
	}
	/**
	 * @author: sminutoli
	 * @usage:  Su uso es para la herencia
	 */
	private function refreshData():Void {
		return;
	}
	
	public function setSize( wh:Point ):Void {
		this.size = wh;
		refreshSize();
	}
	/**
	 * @author: sminutoli
	 * @usage:  Su uso es para la herencia
	 */
	private function refreshSize():Void {
		return;
	}
	
	private function getChild(name:String) {
		return this[name];
	}
	
	/**
	 * @author: sminutoli
	 * @usage:  Su uso es para la herencia
	 */
	public function childLoaded( evnt ):Void {
		return;
	}
	
	private function registerTween( key:String, tween:Tween, keepAlive:Boolean, listenEnd:Boolean, listenChange:Boolean ):Void {
		if ( !tweens ) tweens = new Array();
		removeTween( key ); //si existe un tween con ese key lo elimino
		
		var oListener:Object = new Object();
		tweens.push( { key: key, tween: tween, listener: oListener } ); //agrego al array interno
		
		var root = this;
		if( listenChange ){
			oListener.onMotionChanged = function() {
				root.tweenChanged( key, tween );
			}
		}
		oListener.onMotionFinished = function() {
			// busco el tween y lo saco del array, queda libre para que el garbage collector lo liquide
			for (var i:Number = 0; i < root.tweens.length ; i++) {
				if ( root.tweens[i].key == key ) {
					if ( !keepAlive ) root.tweens.splice( i, 1 );
					if ( listenEnd ) {
						root.tweenFinished( key, tween );
					}				
				}
			}
		}
		tween.addListener( oListener );
		
	}
	/**
	 * @author: sminutoli
	 * @usage:  Su uso es para la herencia
	 */
	private function tweenFinished(tweenKey, tween) {
		return;
	}
	/**
	 * @author: sminutoli
	 * @usage:  Su uso es para la herencia
	 */
	private function tweenChanged(tweenKey, tween) {
		return;
	}
	
	private function removeTween( key:String ):Void {
		for (var i:Number = 0; i < this.tweens.length ; i++) {
			if ( this.tweens[i].key == key ) {
				//trace("removeTween= " + key);
				tweens[i].tween.stop();
				tweens.splice( i, 1 );
			}
		}		
	}
	
	private function getTween( key:String ):Tween {
		for (var i:Number = 0; i < this.tweens.length ; i++) {
			if ( this.tweens[i].key == key ) return this.tweens[i].tween;
		}		
	}
	
	public function isShowed():Boolean {
		return bShowed;
	}
	
	public function show() {
		showEnd();
	}
	private function showEnd() {
		bShowed = true;
		dispatchEvent( { type: BaseClipEvent.SHOW_END, target: this } );
	}
	
	public function hide() {
		hideEnd();
	}
	private function hideEnd() {
		bShowed = false;
		dispatchEvent( { type: BaseClipEvent.HIDE_END, target: this } );
	}
		
}